package cn.easyutil.util.platform.wechat.util;

import cn.easyutil.util.javaUtil.*;
import cn.easyutil.util.platform.base.PlatfromUserInfo;
import cn.easyutil.util.platform.wechat.base.WeChatMessage;
import cn.easyutil.util.platform.wechat.base.WeChatAccount;
import cn.easyutil.util.platform.wechat.util.bean.UserAccessTokenBean;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信公众号操作
 */
public class WeChatPublicOperation {
    /** 获取全局accessToken的url */
    private String getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{APPID}&secret=#{APPSECRET}";
    /** 获取用户信息第一步，获取code */
    private static String getCodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{APPID}&redirect_uri=#{REDIRECT_URI}&response_type=code&scope=#{SCOPE}&state=#{STATE}#wechat_redirect";
    /** 获取用户信息第二步，获取UserAccessToken */
    private String getUserAccessToken = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=#{APPID}&secret=#{APPSECRET}&code=#{CODE}&grant_type=authorization_code";
    /** 获取用户信息第三步，刷新UserAccessToken */
    private String refreshUserAceessToken = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=#{APPID}&grant_type=refresh_token&refresh_token=#{REFRESH_TOKEN}";
    /** 获取用户基本信息 */
    private String getUserInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=#{ACCESS_TOKEN}&openid=#{OPENID}&lang=zh_CN";
    /** 发送模板消息通知url */
    private String sendMsg_url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=#{ACCESS_TOKEN}";

    private WeChatAccount account;

    public WeChatPublicOperation(WeChatAccount account){
        this.account = account;
    }

    /**
     * 公众号登陆
     * @param code
     * @return
     */
    public PlatfromUserInfo login(String code){
        return getUserInfo(code);
    }

    /**
     * 获取用户信息第二步,获取用户的accesstoken信息 { "access_token":"ACCESS_TOKEN",
     * "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID",
     * "scope":"SCOPE" }
     * @return
     */
    public UserAccessTokenBean getUserAccessToken(String code) {
        String url = getUserAccessToken
                .replace("#{APPID}", account.getAppid())
                .replace("#{APPSECRET}", account.getAppsecret())
                .replace("#{CODE}",code);
        String result =  HttpUtil.doUrl(url,"GET");
        return JsonUtil.jsonToBean(result, UserAccessTokenBean.class);
    }

    /**
     * 获取用户信息第三步，如果accessToken过期，则刷新AccessToken { "access_token":"ACCESS_TOKEN",
     * "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID",
     * "scope":"SCOPE" }
     */
    public UserAccessTokenBean refreshUserAccessToken(String refreshToken) {
        String url = refreshUserAceessToken
                .replace("#{APPID}", account.getAppid())
                .replace("#{REFRESH_TOKEN}", refreshToken);
        String result = HttpUtil.doUrl(url,"GET");
        return JsonUtil.jsonToBean(result, UserAccessTokenBean.class);
    }

    /** 获取用户的基本信息 */
    public PlatfromUserInfo getUserInfo(String accessToken, String openid) {
        String url = getUserInfo
                .replace("#{ACCESS_TOKEN}", accessToken)
                .replace("#{OPENID}", openid);
        String result =  HttpUtil.doUrl(url,"GET");
        Map<String, Object> map = JsonUtil.jsonToMap(result);
        PlatfromUserInfo user = new PlatfromUserInfo();
        if(map.get("city") != null){
            user.setAddress(map.get("city").toString());
        }
        if(map.get("headimgurl") != null){
            user.setHeaderImg(map.get("headimgurl").toString());
        }
        if(map.get("nickname") != null){
            user.setNickName(map.get("nickname").toString());
        }
        if(map.get("sex") != null){
            String sex = map.get("sex").toString();
            user.setSex(sex.equals("1")?1:0);
        }
        if(map.get("openid") != null){
            user.setUniqueId(map.get("openid").toString());
        }
        user.setAsAll(map);
        return user;
    }

    /**
     * 获取用户信息
     * @param code
     * @return
     */
    public PlatfromUserInfo getUserInfo(String code){
        UserAccessTokenBean acc = getUserAccessToken(code);
        return getUserInfo(acc.getAccess_token(), acc.getOpenid());
    }

    /**
     *
     * 向用户发送消息模板内容
     *
     * @param openId
     *            用户在公众号下的唯一标识（接收人）
     * @param templateId
     *            微信公众号配置的消息模板
     * @param message
     *            发送内容封装
     * @return
     */
    public boolean pushMessage(String openId, String templateId, WeChatMessage message) {
        return pushMessage(openId, templateId, null, message);
    }


    /**
     * 获取全局的accesstoken
     * @return
     */
    public String getGlobalAccessToken(){
        String url = getAccessTokenUrl
                .replace("#{APPID}", account.getAppid())
                .replace("#{APPSECRET}", account.getAppsecret());
        String accessToken = HttpUtil.doUrl(url,"GET");
        if (accessToken != null) {
            Map<String, Object> map = JsonUtil.jsonToMap(accessToken);
            if(map.get("access_token") != null){
                return map.get("access_token").toString();
            }
        }
        return null;
    }
    /**
     * 向用户发送消息模板内容
     *
     * @param openId
     *            用户在公众号下的唯一标识（接收人）
     * @param templateId
     *            微信公众号配置的消息模板
     * @param url
     *            用户点击消息后的跳转
     * @param message
     *            发送内容封装
     * @return
     */
    public boolean pushMessage(String openId, String templateId, String url, WeChatMessage message) {
        Map<String, Object> finalMessage = new HashMap<String, Object>();
        finalMessage.put("touser", openId);
        finalMessage.put("template_id", templateId);
        if (!StringUtil.isEmpty(url)) {
            finalMessage.put("url", url);
        }
        Map<String, Object> mess = new HashMap<String, Object>();
        List<WeChatMessage> params = ObjectUtil.getAttributeValue(message, "params");
        for (int i = 0; i < params.size(); i++) {
            Map<String, String> param = new HashMap<String, String>();
            param.put("value", ObjectUtil.getAttributeValue(params.get(i), "value"));
            param.put("color", ObjectUtil.getAttributeValue(params.get(i), "color"));
            mess.put(ObjectUtil.getAttributeValue(params.get(i), "paramName"), param);
        }
        finalMessage.put("data", mess);
        String result = HttpUtil.doUrl(this.sendMsg_url.replace("#{ACCESS_TOKEN}", getGlobalAccessToken()), "POST", null,
                JsonUtil.beanToJson(finalMessage));
        Map<String, Object> jsonToMap = JsonUtil.jsonToMap(result);
        if (jsonToMap.get("errcode") != null && jsonToMap.get("errcode").equals(0) && jsonToMap.get("errmsg") != null
                && jsonToMap.get("errmsg").equals("ok")) {
            return true;
        }
        LoggerUtil.error(this.getClass(), "发送微信模板消息失败:" + result);
        return false;
    }
}
